OOP and IF
- 2024-10-29
- 별칭: OOP와 IF문
OOP가 기존의 어떤 개념을 대체하는지 생각해보면 유익할 때가 있다. 레퍼런스는 포인터에서 산술연산을 제거하고, 구조적 프로그래밍은 흐름 제어에서 비구조적 흐름 제어(GOTO 문)를 제거하며, OOP는 상위 계층의 모듈화를 방해하는 if
, switch
, match
등 선택문을 제거한다. (2005-2007년 사이에 작성)
레퍼런스와 포인터 산술연산
C 언어의 포인터는 산술 연산을 허용하는 날것의 주소지칭 수단이다. 자바나 C#의 레퍼런스(reference)는 포인터에서 산술연산(arithmatic operations)을 제약해서 보안성, 편의성, GC 효율성 등의 장점을 취한다.
구조적 프로그래밍과 GOTO 문
구조적 프로그래밍은 프로그램의 흐름을 제어하는 방법 중 GOTO 문을 제거한다. 다익스트라의 표현을 빌어 일반화하자면 의미있는 프로그래머 독립 좌표계를 훼손하는 장치를 제거하는 게 중요하다. 구조적 프로그램 정리에 따르면 GOTO가 없더라도 다음 세 가지 수단의 조합으로 흐름 제어를 표현할 수 있다:
- 순서(sequence): 쉽게 말해서 재귀적인 함수 호출과 리턴으로 구성된 코드가 위에서 아래로 실행되는 것
- 선택(selection): 쉽게 말해서
if
,switch
,match
- 반복(iteration): 쉽게 말해서
while
,do
,until
,repeat
,for
조건문과 결합된 GOTO 문은 날것의 흐름제어 수단인데, 구조적 프로그래밍은 이를 제약함으로써 이해가능성, 모듈화 등의 장점을 취한다.
OOP와 IF 문
혹자는 OOP가 구조적 프로그래밍을 대체한다고 말하는데 이는 1/3 정도만 맞는 표현이다. OOP는 서브타입 다형성을 통해 구조적 프로그래밍의 세 가지 흐름 제어 수단 중 선택, 즉 if
, switch
, match
등을 대체한다고 생각해볼 수 있다.
조건문이란 애초에 분기 선택(selection) 메커니즘인데 ‘선택’이란 특정 변수의 값에 따라 이후에 실행할 코드가 달라지도록 하는 걸 말한다. if
문에서는 조건절의 boolean
값에 따라 선택이 수행되는 것이고, 서브타입 다형성에서는 메시지를 수신하는 인스턴스의 타입에 따라 선택이 수행된다.
다음은 전통적인 방식:
if(mediaType === "monitor") {
renderToMonitor();
} else if(mediaType === "printer") {
renderToPrinter();
} else {
throw new IllegalArgumentException("Unknown media: " + mediaType);
}
다음은 서브타입 다형성를 활용한 방식:
abstact class Media() { void render() }
class Monitor extends Media() { void render() { /* ... */ } }
class Printer extends Media() { void render() { /* ... */ } }
// ...
media.render();
서브타입 다형성과 이를 이용한 의존성 역전이 OOP를 특징지을 정도로 중요한 관점일 수 있나? 몇몇 이들은 그렇다고 주장한다.
프로그램이 어떤 언어로 작성되었는지는 중요치 않습니다. 만약 의존성이 역전되어 있다면 이는 객체지향적 설계인 것입니다. (It doesn’t matter what language a program is written in. If its dependencies are inverted, it has an OO design.)
—Robert Cecil Martin, Agile software development (book)
오해의 소지가 있으니 부연하자면, 모든 if
를 제거해야 객체지향 디자인이라는 주장은 아니다. 마틴 파울러의 설명을 인용하자면 이렇다:
우리가 조건문에 무조건적으로 반대하는 건 아니다. 이 책(리팩토링)의 초판에서는 “switch 문”이라는 이름의 악취가 있었다. 1990년대 후반에는 슬프게도 다형성이 충분히 널리 인식되지 못했기에, 사람들이
switch
대신 다형성을 선택하는 게 이롭다고 봤기 때문이다. —Refactoring: Improving the design of existing code
캡슐화와 정보 은닉
보통 OOP의 세 가지 특징으로 다형성, 캡슐화, 정보 은닉을 꼽는데 이 중 다형성이 특별히 더 중요하다고 볼 수 있을까?
세 가지 모두 중요하지만 캡슐화나 정보 은닉은 OOP 이전에도 원래 있던 개념들이라는 점에서, 다형성은 상대적으로 눈에 띄는 차별점이다.
if를 모두 제거해야 진정한 OOP인가?
두 가지를 이야기할 수 있겠다.
- 첫째, “진정한 OOP”는 정의하기도 모호하고 별로 추구해야할 가치도 아니다.
- 둘째, 모든
if
가 아니라 상위 계층의 모듈화를 저해하는if
를 제거하는 게 중요하다.
OOP가 서브타입 다형성을 써서 상위 계층의 모듈화를 저해하는 if
를 대체한다는 관점은 OOP를 이해하는 여러 유익한 관점 중 하나다.